<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>聊天气泡集成测试</title>
    <style>
        body {
            margin: 0;
            padding: 20px;
            font-family: 'Microsoft YaHei', sans-serif;
            background: #2c3e50;
            color: white;
        }
        
        .test-container {
            max-width: 800px;
            margin: 0 auto;
            background: rgba(255, 255, 255, 0.1);
            padding: 20px;
            border-radius: 10px;
        }
        
        .test-controls {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        
        .test-button {
            padding: 10px 15px;
            background: #3498db;
            border: none;
            border-radius: 5px;
            color: white;
            cursor: pointer;
            transition: background 0.3s;
        }
        
        .test-button:hover {
            background: #2980b9;
        }
        
        .status {
            background: rgba(0, 0, 0, 0.3);
            padding: 15px;
            border-radius: 5px;
            margin-top: 20px;
            font-family: 'Courier New', monospace;
            font-size: 12px;
        }
        
        .success {
            color: #2ecc71;
        }
        
        .error {
            color: #e74c3c;
        }
        
        .info {
            color: #f39c12;
        }
    </style>
</head>
<body>
    <div class="test-container">
        <h1>聊天气泡管理器集成测试</h1>
        
        <div class="test-controls">
            <button class="test-button" onclick="testBasicFunctionality()">基础功能测试</button>
            <button class="test-button" onclick="testMessageProcessing()">消息处理测试</button>
            <button class="test-button" onclick="testDistanceScaling()">距离缩放测试</button>
            <button class="test-button" onclick="testAutoRemoval()">自动移除测试</button>
            <button class="test-button" onclick="testMultipleBubbles()">多气泡测试</button>
            <button class="test-button" onclick="runAllTests()">运行所有测试</button>
        </div>
        
        <div id="status" class="status">
            准备运行测试...
        </div>
    </div>

    <script>
        // 测试状态管理
        let testResults = [];
        
        function log(message, type = 'info') {
            const statusElement = document.getElementById('status');
            const timestamp = new Date().toLocaleTimeString();
            const logEntry = `[${timestamp}] ${message}`;
            
            statusElement.innerHTML += `<div class="${type}">${logEntry}</div>`;
            statusElement.scrollTop = statusElement.scrollHeight;
            
            console.log(logEntry);
        }
        
        function clearLog() {
            document.getElementById('status').innerHTML = '';
            testResults = [];
        }
        
        // 模拟实体类
        class MockEntity {
            constructor(id, type, position) {
                this.id = id;
                this.type = type;
                this.position = position;
            }
            
            getId() { return this.id; }
            getType() { return this.type; }
            getPosition() { return this.position; }
        }
        
        // 模拟THREE.js相机
        class MockCamera {
            constructor() {
                this.position = { x: 0, y: 0, z: 0 };
            }
        }
        
        // 简化的ChatBubbleManager用于测试
        class TestChatBubbleManager {
            constructor() {
                this.bubbles = new Map();
                this.container = null;
                this.camera = null;
                this.defaultDuration = 3000;
                this.maxDistance = 20;
                this.createContainer();
                this.addStyles();
            }
            
            createContainer() {
                // 移除旧容器
                const oldContainer = document.getElementById('chat-bubbles-container');
                if (oldContainer) {
                    oldContainer.remove();
                }
                
                this.container = document.createElement('div');
                this.container.id = 'chat-bubbles-container';
                this.container.style.cssText = `
                    position: fixed;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                    pointer-events: none;
                    z-index: 100;
                `;
                document.body.appendChild(this.container);
            }
            
            addStyles() {
                const existingStyle = document.getElementById('chat-bubble-styles');
                if (existingStyle) {
                    existingStyle.remove();
                }
                
                const style = document.createElement('style');
                style.id = 'chat-bubble-styles';
                style.textContent = `
                    .chat-bubble {
                        position: absolute;
                        background: rgba(0, 0, 0, 0.85);
                        color: white;
                        padding: 10px 14px;
                        border-radius: 16px;
                        font-family: 'Microsoft YaHei', sans-serif;
                        font-size: 14px;
                        max-width: 250px;
                        word-wrap: break-word;
                        text-align: left;
                        border: 2px solid rgba(255, 255, 255, 0.3);
                        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
                        transform: translate(-50%, -100%);
                        animation: chatBubbleAppear 0.4s ease-out;
                        line-height: 1.4;
                        white-space: pre-wrap;
                    }
                    
                    .chat-bubble::after {
                        content: '';
                        position: absolute;
                        top: 100%;
                        left: 50%;
                        transform: translateX(-50%);
                        border: 10px solid transparent;
                        border-top-color: rgba(0, 0, 0, 0.85);
                    }
                    
                    .chat-bubble.fade-out {
                        animation: chatBubbleFadeOut 0.6s ease-in forwards;
                    }
                    
                    @keyframes chatBubbleAppear {
                        0% {
                            opacity: 0;
                            transform: translate(-50%, -100%) scale(0.6);
                        }
                        100% {
                            opacity: 1;
                            transform: translate(-50%, -100%) scale(1);
                        }
                    }
                    
                    @keyframes chatBubbleFadeOut {
                        0% {
                            opacity: 1;
                            transform: translate(-50%, -100%) scale(1);
                        }
                        100% {
                            opacity: 0;
                            transform: translate(-50%, -100%) scale(0.8);
                        }
                    }
                `;
                document.head.appendChild(style);
            }
            
            showBubble(entity, message, duration) {
                const bubbleId = entity.getId();
                
                if (this.bubbles.has(bubbleId)) {
                    this.removeBubble(bubbleId);
                }
                
                const element = this.createBubbleElement(message);
                const bubble = {
                    id: bubbleId,
                    entity,
                    message,
                    element,
                    startTime: Date.now(),
                    duration: duration || this.defaultDuration,
                    isVisible: true
                };
                
                this.container.appendChild(element);
                this.bubbles.set(bubbleId, bubble);
                this.updateBubblePosition(bubble);
                
                setTimeout(() => {
                    this.removeBubble(bubbleId);
                }, bubble.duration);
                
                return true;
            }
            
            createBubbleElement(message) {
                const element = document.createElement('div');
                element.className = 'chat-bubble';
                element.textContent = this.processMessageText(message);
                return element;
            }
            
            processMessageText(message) {
                if (message.length <= 30) {
                    return message;
                }
                
                // 简单的换行处理
                const words = message.split('');
                let result = '';
                let currentLine = '';
                
                for (const char of words) {
                    if (currentLine.length >= 25 && (char === '，' || char === '。' || char === '！' || char === '？')) {
                        result += currentLine + char + '\n';
                        currentLine = '';
                    } else {
                        currentLine += char;
                    }
                }
                
                if (currentLine) {
                    result += currentLine;
                }
                
                return result.trim();
            }
            
            updateBubblePosition(bubble) {
                // 简单的位置设置 - 随机位置用于测试
                const x = 200 + Math.random() * 400;
                const y = 150 + Math.random() * 200;
                
                bubble.element.style.left = `${x}px`;
                bubble.element.style.top = `${y}px`;
                bubble.element.style.display = 'block';
            }
            
            removeBubble(bubbleId) {
                const bubble = this.bubbles.get(bubbleId);
                if (!bubble) return;
                
                bubble.element.classList.add('fade-out');
                bubble.isVisible = false;
                
                setTimeout(() => {
                    if (bubble.element.parentNode) {
                        bubble.element.parentNode.removeChild(bubble.element);
                    }
                    this.bubbles.delete(bubbleId);
                }, 600);
            }
            
            clear() {
                for (const bubbleId of this.bubbles.keys()) {
                    this.removeBubble(bubbleId);
                }
            }
            
            getActiveBubbleCount() {
                return Array.from(this.bubbles.values()).filter(b => b.isVisible).length;
            }
            
            hasActiveBubble(entityId) {
                const bubble = this.bubbles.get(entityId);
                return bubble ? bubble.isVisible : false;
            }
        }
        
        // 创建测试实例
        let chatBubbleManager;
        
        function initializeTest() {
            chatBubbleManager = new TestChatBubbleManager();
            log('聊天气泡管理器已初始化', 'success');
        }
        
        // 测试函数
        async function testBasicFunctionality() {
            clearLog();
            log('开始基础功能测试...', 'info');
            
            try {
                initializeTest();
                
                // 测试创建气泡
                const entity = new MockEntity('test1', '牛', { x: 0, y: 0, z: 0 });
                const result = chatBubbleManager.showBubble(entity, '测试消息', 2000);
                
                if (result) {
                    log('✓ 气泡创建成功', 'success');
                    testResults.push({ test: '基础功能', result: 'PASS' });
                } else {
                    log('✗ 气泡创建失败', 'error');
                    testResults.push({ test: '基础功能', result: 'FAIL' });
                }
                
                // 检查气泡是否存在
                if (chatBubbleManager.hasActiveBubble('test1')) {
                    log('✓ 气泡状态检查正常', 'success');
                } else {
                    log('✗ 气泡状态检查失败', 'error');
                }
                
            } catch (error) {
                log(`✗ 基础功能测试出错: ${error.message}`, 'error');
                testResults.push({ test: '基础功能', result: 'ERROR' });
            }
        }
        
        async function testMessageProcessing() {
            clearLog();
            log('开始消息处理测试...', 'info');
            
            try {
                initializeTest();
                
                const testMessages = [
                    '短消息',
                    '这是一个中等长度的消息，用来测试换行功能',
                    '这是一个非常长的消息，用来测试气泡的文本处理能力。它应该能够正确地处理长文本，并在适当的位置进行换行，以确保用户能够清楚地阅读所有内容。'
                ];
                
                const entities = testMessages.map((msg, index) => 
                    new MockEntity(`test${index}`, `实体${index}`, { x: index * 100, y: 0, z: 0 })
                );
                
                for (let i = 0; i < testMessages.length; i++) {
                    chatBubbleManager.showBubble(entities[i], testMessages[i], 3000);
                    log(`✓ 消息 ${i + 1} 处理完成: "${testMessages[i].substring(0, 20)}..."`, 'success');
                }
                
                log(`✓ 所有消息处理完成，当前活跃气泡数: ${chatBubbleManager.getActiveBubbleCount()}`, 'success');
                testResults.push({ test: '消息处理', result: 'PASS' });
                
            } catch (error) {
                log(`✗ 消息处理测试出错: ${error.message}`, 'error');
                testResults.push({ test: '消息处理', result: 'ERROR' });
            }
        }
        
        async function testDistanceScaling() {
            clearLog();
            log('开始距离缩放测试...', 'info');
            
            try {
                initializeTest();
                
                // 模拟不同距离的实体
                const distances = [5, 10, 15, 25]; // 最后一个超出最大距离
                const entities = distances.map((dist, index) => 
                    new MockEntity(`dist${index}`, `距离${dist}`, { x: dist, y: 0, z: 0 })
                );
                
                for (let i = 0; i < entities.length; i++) {
                    chatBubbleManager.showBubble(entities[i], `我在${distances[i]}格距离`, 3000);
                    log(`✓ 距离 ${distances[i]} 的气泡已创建`, 'success');
                }
                
                log('✓ 距离缩放测试完成', 'success');
                testResults.push({ test: '距离缩放', result: 'PASS' });
                
            } catch (error) {
                log(`✗ 距离缩放测试出错: ${error.message}`, 'error');
                testResults.push({ test: '距离缩放', result: 'ERROR' });
            }
        }
        
        async function testAutoRemoval() {
            clearLog();
            log('开始自动移除测试...', 'info');
            
            try {
                initializeTest();
                
                const entity = new MockEntity('removal_test', '测试实体', { x: 0, y: 0, z: 0 });
                chatBubbleManager.showBubble(entity, '这个气泡将在1秒后消失', 1000);
                
                log('✓ 气泡已创建，等待自动移除...', 'info');
                
                setTimeout(() => {
                    if (!chatBubbleManager.hasActiveBubble('removal_test')) {
                        log('✓ 气泡自动移除成功', 'success');
                        testResults.push({ test: '自动移除', result: 'PASS' });
                    } else {
                        log('✗ 气泡未能自动移除', 'error');
                        testResults.push({ test: '自动移除', result: 'FAIL' });
                    }
                }, 1500);
                
            } catch (error) {
                log(`✗ 自动移除测试出错: ${error.message}`, 'error');
                testResults.push({ test: '自动移除', result: 'ERROR' });
            }
        }
        
        async function testMultipleBubbles() {
            clearLog();
            log('开始多气泡测试...', 'info');
            
            try {
                initializeTest();
                
                const entities = [];
                const messages = [
                    '我是第一个气泡',
                    '我是第二个气泡',
                    '我是第三个气泡',
                    '我是第四个气泡'
                ];
                
                for (let i = 0; i < 4; i++) {
                    entities.push(new MockEntity(`multi${i}`, `实体${i}`, { x: i * 50, y: 0, z: 0 }));
                }
                
                // 同时创建多个气泡
                for (let i = 0; i < entities.length; i++) {
                    setTimeout(() => {
                        chatBubbleManager.showBubble(entities[i], messages[i], 3000);
                        log(`✓ 气泡 ${i + 1} 已创建`, 'success');
                        
                        if (i === entities.length - 1) {
                            setTimeout(() => {
                                const activeCount = chatBubbleManager.getActiveBubbleCount();
                                log(`✓ 多气泡测试完成，当前活跃气泡数: ${activeCount}`, 'success');
                                testResults.push({ test: '多气泡', result: 'PASS' });
                            }, 100);
                        }
                    }, i * 200);
                }
                
            } catch (error) {
                log(`✗ 多气泡测试出错: ${error.message}`, 'error');
                testResults.push({ test: '多气泡', result: 'ERROR' });
            }
        }
        
        async function runAllTests() {
            clearLog();
            log('开始运行所有测试...', 'info');
            
            const tests = [
                testBasicFunctionality,
                testMessageProcessing,
                testDistanceScaling,
                testAutoRemoval,
                testMultipleBubbles
            ];
            
            for (let i = 0; i < tests.length; i++) {
                await new Promise(resolve => {
                    setTimeout(async () => {
                        await tests[i]();
                        resolve();
                    }, i * 1000);
                });
            }
            
            // 显示测试结果摘要
            setTimeout(() => {
                log('\n=== 测试结果摘要 ===', 'info');
                const passed = testResults.filter(r => r.result === 'PASS').length;
                const failed = testResults.filter(r => r.result === 'FAIL').length;
                const errors = testResults.filter(r => r.result === 'ERROR').length;
                
                log(`通过: ${passed}, 失败: ${failed}, 错误: ${errors}`, 
                    passed === testResults.length ? 'success' : 'error');
                
                testResults.forEach(result => {
                    const status = result.result === 'PASS' ? '✓' : '✗';
                    const type = result.result === 'PASS' ? 'success' : 'error';
                    log(`${status} ${result.test}: ${result.result}`, type);
                });
            }, 2000);
        }
        
        // 页面加载完成后初始化
        window.addEventListener('load', () => {
            log('聊天气泡集成测试页面已加载', 'success');
            log('点击按钮开始测试', 'info');
        });
    </script>
</body>
</html>